home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / arpcmd.c < prev    next >
C/C++ Source or Header  |  1993-07-26  |  9KB  |  386 lines

  1. /* ARP commands
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by G1EMM
  5.  *
  6.  * Mods by SM6RPZ
  7.  * 1992-05-28 - Added interface to "arp add ..."-command.
  8.  * 1992-07-26 - Small cosmetic changes here and there.
  9.  */
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include "global.h"
  13. #include "config.h"
  14. #include "mbuf.h"
  15. #include "timer.h"
  16. #include "internet.h"
  17. #include "ip.h"
  18. #include "enet.h"
  19. #include "ax25.h"
  20. #include "arp.h"
  21. #include "netuser.h"
  22. #include "cmdparse.h"
  23. #include "commands.h"
  24. #include "iface.h"
  25. #include "rspf.h"
  26. #include "socket.h"
  27. #include "domain.h"
  28. #include "session.h"
  29.  
  30. int Arp_Sort=1;  /* set Initial sort mode */
  31.  
  32. static int doarpsort __ARGS((int argc,char *argv[],void *p));
  33. static void make_arp_string __ARGS((struct arp_tab *ap,char *buf));
  34. static int doarpadd __ARGS((int argc,char *argv[],void *p));
  35. static int doarpdrop __ARGS((int argc,char *argv[],void *p));
  36. static int doarpflush __ARGS((int argc,char *argv[],void *p));
  37. static int doarppoll __ARGS((int argc,char *argv[],void *p));
  38. static int doarpeaves __ARGS((int argc,char *argv[],void *p));
  39. static int doarpqueue __ARGS((int argc,char *argv[],void *p));
  40. static void dumparp __ARGS((void));
  41.  
  42. static struct cmds DFAR Arpcmds[] = {
  43.     "add", doarpadd, 0, 4,
  44.     "arp add <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>",
  45.  
  46.     "drop", doarpdrop, 0, 3,
  47.     "arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>",
  48.  
  49.     "eaves", doarpeaves, 0, 0, NULLCHAR,
  50.  
  51.     "flush", doarpflush, 0, 0,
  52.     NULLCHAR,
  53.  
  54.     "maxq", doarpqueue, 0, 0, NULLCHAR,
  55.  
  56.     "poll", doarppoll, 0, 0, NULLCHAR,
  57.  
  58.     "publish", doarpadd, 0, 4,
  59.     "arp publish <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>",
  60.  
  61.     "sort",    doarpsort, 0, 0,
  62.     NULLCHAR,
  63.  
  64.     NULLCHAR,
  65. };
  66.  
  67. char *Arptypes[] = {
  68.     "NET/ROM",
  69.     "10 Mb Ethernet",
  70.     "3 Mb Ethernet",
  71.     "AX.25",
  72.     "Pronet",
  73.     "Chaos",
  74.     "",
  75.     "Arcnet",
  76.     "Appletalk"
  77. };
  78.  
  79. int
  80. doarp(argc,argv,p)
  81. int argc;
  82. char *argv[];
  83. void *p;
  84. {
  85.     if(argc < 2){
  86.         dumparp();
  87.         return 0;
  88.     }
  89.     return subcmd(Arpcmds,argc,argv,p);
  90. }
  91.  
  92. static
  93. doarpadd(argc,argv,p)
  94. int argc;
  95. char *argv[];
  96. void *p;
  97. {
  98.     int16 hardware;
  99.     int32 addr;
  100.     char *hwaddr;
  101.     struct arp_tab *ap;
  102.     struct arp_type *at;
  103.     int pub = 0;
  104.     struct iface *iface;
  105.  
  106.     if(argv[0][0] == 'p')    /* Is this entry published? */
  107.         pub = 1;
  108.     if((addr = resolve(argv[1])) == 0){
  109.         tprintf(Badhost,argv[1]);
  110.         return 1;
  111.     }
  112.     if(argc == 4 && tolower(argv[2][0]) != 'n') {
  113.         tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  114.         pub ? "publish" : "add");
  115.         return -1;
  116.     }
  117.     /* This is a kludge. It really ought to be table driven */
  118.     switch(tolower(argv[2][0])){
  119.     case 'n':    /* Net/Rom pseudo-type */
  120.         argc = 5;
  121.         argv[4] = "netrom";    /* Force use of netrom interface */
  122.         hardware = ARP_NETROM;
  123.         break;
  124.     case 'e':    /* "ether" */
  125.         hardware = ARP_ETHER;
  126.         break;        
  127.     case 'a':    /* "ax25" */
  128.         switch(tolower(argv[2][1])) {
  129.         case 'x':
  130.             hardware = ARP_AX25;
  131.             break;
  132.         case 'r':
  133.             hardware = ARP_ARCNET;
  134.             break;
  135.         default:
  136.             tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  137.                 pub ? "publish" : "add");
  138.             return -1;
  139.         }
  140.         break;
  141.     case 'm':    /* "mac appletalk" */
  142.         hardware = ARP_APPLETALK;
  143.         break;
  144.     default:
  145.         tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  146.             pub ? "publish" : "add");
  147.         return -1;
  148.     }
  149.     if((iface = if_lookup(argv[4])) == NULLIF) {
  150.         tprintf("No such interface %s\n", argv[4]);
  151.         return 1;
  152.     }
  153.     /* If an entry already exists, clear it */
  154.     if((ap = arp_lookup(hardware,addr,iface)) != NULLARP)
  155.         arp_drop(ap);
  156.  
  157.     at = &Arp_type[hardware];
  158.     if(at->scan == NULLFP){
  159.         tputs("Attach device first\n");
  160.         return 1;
  161.     }
  162.     /* Allocate buffer for hardware address and fill with remaining args */
  163.     hwaddr = mallocw(at->hwalen);
  164.     /* Destination address */
  165.     (*at->scan)(hwaddr,argv[3]);
  166.     ap = arp_add(addr,hardware,hwaddr,pub,iface);    /* Put in table */
  167.     free(hwaddr);                    /* Clean up */
  168.     stop_timer(&ap->timer);                /* Make entry permanent */
  169.     set_timer(&ap->timer,0L);
  170. #ifdef    RSPF
  171.     rspfarpupcall(addr,hardware,NULLIF);  /* Do a RSPF upcall */
  172. #endif    /* RSPF */
  173.     return 0;
  174. }
  175.  
  176. static int
  177. doarpeaves(argc,argv,p)
  178. int argc ;
  179. char *argv[] ;
  180. void *p;
  181. {
  182.     return(dosetflag(argc,argv,p,ARP_EAVESDROP, 0));
  183. }
  184.  
  185. static int
  186. doarppoll(argc,argv,p)
  187. int argc ;
  188. char *argv[] ;
  189. void *p;
  190. {
  191.     return(dosetflag(argc,argv,p,ARP_KEEPALIVE, 0));
  192. }
  193.  
  194. int Maxarpq = 5;
  195.  
  196. static int
  197. doarpqueue(argc,argv,p)
  198. int argc ;
  199. char *argv[] ;
  200. void *p;
  201. {
  202.     return setint(&Maxarpq,"Max queue",argc,argv);
  203. }
  204.  
  205.  
  206. /* Remove an ARP entry */
  207. static
  208. doarpdrop(argc,argv,p)
  209. int argc;
  210. char *argv[];
  211. void *p;
  212. {
  213.     int16 hardware;
  214.     int32 addr;
  215.     struct arp_tab *ap;
  216.     struct iface *iface;
  217.  
  218.     if((addr = resolve(argv[1])) == 0){
  219.         tprintf(Badhost,argv[1]);
  220.         return 1;
  221.     }
  222.     if(argc == 3 && tolower(argv[2][0]) != 'n') {
  223.         tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  224.         return -1;
  225.     }
  226.     /* This is a kludge. It really ought to be table driven */
  227.     switch(tolower(argv[2][0])){
  228.     case 'n':
  229.         argc = 4;
  230.         argv[3] = "netrom";    /* Force use of netrom interface */
  231.         hardware = ARP_NETROM;
  232.         break;
  233.     case 'e':    /* "ether" */
  234.         hardware = ARP_ETHER;
  235.         break;        
  236.     case 'a':    /* "ax25" */
  237.         switch(tolower(argv[2][1])) {
  238.         case 'x':
  239.             hardware = ARP_AX25;
  240.             break;
  241.         case 'r':
  242.             hardware = ARP_ARCNET;
  243.             break;
  244.         default:
  245.             tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  246.             return -1;
  247.         }
  248.         break;
  249.     case 'm':    /* "mac appletalk" */
  250.         hardware = ARP_APPLETALK;
  251.         break;
  252.     default:
  253.         tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  254.         return -1;
  255.     }
  256.     if((iface = if_lookup(argv[3])) == NULLIF) {
  257.         tprintf("No such interface %s\n", argv[3]);
  258.         return 1;
  259.     }
  260.     if((ap = arp_lookup(hardware,addr,iface)) == NULLARP)
  261.         return -1;
  262.     arp_drop(ap);
  263.     return 0;    
  264. }
  265.  
  266. /* Flush all automatic entries in the arp cache */
  267. static int
  268. doarpflush(argc,argv,p)
  269. int argc;
  270. char *argv[];
  271. void *p;
  272. {
  273.     register struct arp_tab *ap;
  274.     struct arp_tab *aptmp;
  275.     int i;
  276.  
  277.     for(i=0;i<HASHMOD;i++){
  278.         for(ap = Arp_tab[i];ap != NULLARP;ap = aptmp){
  279.             aptmp = ap->next;
  280.             if(dur_timer(&ap->timer) != 0)
  281.                 arp_drop(ap);
  282.         }
  283.     }
  284.     return 0;
  285. }
  286.  
  287. /* Dump ARP table */
  288. static void
  289. dumparp()
  290. {
  291.     register int i,j,k,flow_tmp;
  292.     register struct arp_tab *ap;
  293.     char *temp;        
  294.     
  295.     flow_tmp=Current->flowmode;
  296.     Current->flowmode=1;
  297.  
  298.     tprintf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n",
  299.      Arp_stat.recv,Arp_stat.badtype,Arp_stat.badaddr,Arp_stat.inreq,
  300.      Arp_stat.replies,Arp_stat.outreq);
  301.  
  302.     for(i=0,j=0;i<HASHMOD;i++)
  303.        for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next,j++);
  304.     
  305.     if (j) {
  306.  
  307.       tprintf("IP addr         Type           Time Q Address           Interface\n");
  308.     
  309.       temp=mallocw(j*80);
  310.     
  311.       for(i=0,k=0;i<HASHMOD;i++) {
  312.          for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next,k+=80)
  313.             make_arp_string(ap,&temp[k]);
  314.       }
  315.  
  316.       if (Arp_Sort) qsort(temp,(size_t)j,80,strcmp);
  317.  
  318.       for(i=0,k=4;i<j;i++,k+=80) {
  319.           tprintf("%s",&temp[k]);
  320.           if(tprintf("\n") == EOF)  break;
  321.       }
  322.       free(temp);
  323.     }
  324.  
  325.     Current->flowmode=flow_tmp;
  326. }
  327.  
  328. void
  329. make_arp_string(ap,buf)
  330. register struct arp_tab *ap;
  331. char *buf;
  332. {
  333.     char e[128];
  334.     unsigned a=0;
  335.     char *name;
  336.  
  337.     if(DTranslate && (name = resolve_a(ap->ip_addr,!DVerbose)) != NULLCHAR) {
  338.         strcpy(buf, name);
  339.         a+=4;
  340.         free(name);
  341.     } else {
  342.         a=sprintf(buf,"%4.4s",inet_ntobos(ap->ip_addr));
  343.     }
  344.  
  345.     a+=sprintf(&buf[a],"%-15.15s ",inet_ntoa(ap->ip_addr));
  346.     a+=sprintf(&buf[a],"%-14.14s ",smsg(Arptypes,NHWTYPES,ap->hardware));
  347.     a+=sprintf(&buf[a],"%4ld ",read_timer(&ap->timer)/1000L);
  348.  
  349.     if(ap->state == ARP_PENDING)
  350.         a+=sprintf(&buf[a],"%1.1u ",len_q(ap->pending));
  351.     else
  352.         a+=sprintf(&buf[a],"  ");
  353.  
  354.     if(ap->state == ARP_VALID){
  355.         if(Arp_type[ap->hardware].format != NULL){
  356.             (*Arp_type[ap->hardware].format)(e,ap->hw_addr);
  357.        } else {
  358.             e[0]='\0';
  359.        }
  360.        a+=sprintf(&buf[a],"%-17.17s ",e);
  361.     } else {
  362.        a+=sprintf(&buf[a],"[unknown]         ");
  363.     }
  364.  
  365.     if (ap->iface)
  366.         a+=sprintf(&buf[a],"%-6.6s ",ap->iface->name);
  367.  
  368.     if(ap->pub)
  369.         a+=sprintf(&buf[a],"(published)");
  370.  
  371.     return;
  372. }
  373.  
  374. /* Sort ARP dump */
  375. static int
  376. doarpsort(argc,argv,p)
  377. int argc ;
  378. char *argv[] ;
  379. void *p;
  380. {
  381.     extern int Arp_Sort;
  382.  
  383.     return setbool(&Arp_Sort,"ARP Sort flag",argc,argv);
  384. }
  385.  
  386.